package com.swipemaster.game.modes;

import com.google.analytics.tracking.android.EasyTracker;
import com.swipemaster.R;
import com.swipemaster.common.CustomGameSettings;
import com.swipemaster.common.Global;
import com.swipemaster.game.GameSurface;
import com.swipemaster.levels.Level;
import com.swipemaster.levels.LevelFactory;
import com.swipemaster.record.IntegerRecord;
import com.swipemaster.record.Record;
import com.swipemaster.record.RecordId;
import com.swipemaster.record.RecordsManager;

public class CustomMode extends GameMode
{
	public CustomMode()
	{
		super(new RecordId(RecordId.CUSTOM_GAME));
	}

	@Override
	public void addModePlayed(boolean isWinner)
	{
		super.addModePlayed(isWinner);
		
		final IntegerRecord record = (IntegerRecord) RecordsManager.getRecord(RecordId.CUSTOM_GAMES_PLAYED);
		record.counter++;

		EasyTracker.getTracker().sendView("Custom Game");
	}

	@Override
	public Level getNewLevel()
	{
		return LevelFactory.getCustomGameLevel();
	}

	@Override
	public int getPlayedTimes()
	{
		final IntegerRecord record = (IntegerRecord) RecordsManager.getRecord(RecordId.CUSTOM_GAMES_PLAYED);
		return record.counter;
	}

	@Override
	public Record getRecord()
	{
		final double time = GameSurface.level.getPlayingTime();
		final int score = getCustomScore(time);
		final IntegerRecord record = new IntegerRecord(RecordId.CUSTOM_GAME);
		record.counter = score;
		return record;
	}

	@Override
	public String getYourScoreText()
	{
		return Global.app.getString(R.string.your_score);
	}

	@Override
	public void playSong()
	{
		Global.app.musicPlayer.playCustomGameSong();
	}

	/** @param time Time of game.
	 * @return Overall score for a custom game. */
	private int getCustomScore(double time)
	{
		final int spawnPeriod = LevelFactory.CUSTOM_GAME_SPAWN_PERIOD;
		final int maxEnemiesWhenLost = (int) (time / spawnPeriod) + 1;
		final int enemiesWhenLost = Math.min(CustomGameSettings.numberOfEnemies, maxEnemiesWhenLost);

		double score = 0.0;

		for (int i = 1; i < enemiesWhenLost; i++)
		{
			score += getCustomScore(spawnPeriod, i);
		}

		final int timeBeforeLastEnemy = (enemiesWhenLost - 1) * spawnPeriod;
		score += getCustomScore(time - timeBeforeLastEnemy, enemiesWhenLost);

		return (int) score;
	}

	/** Helper function when calculating overall custom game score.
	 * @param time Time played.
	 * @param enemies Constant number of enemies when played.
	 * @return Partial result of overall custom score. */
	private double getCustomScore(double time, int enemies)
	{
		final double BOUNCING_IMPORTANCE = 0.75;
		final double SCALE_IMPORTANCE = 0.02;
		final double PARTICLES_IMPORTANCE = 0.01;

		final int b = CustomGameSettings.bouncing ? 1 : 0;
		final int s = CustomGameSettings.enemiesSize;
		final int p = CustomGameSettings.particles ? 1 : 0;

		return time * (1 + (BOUNCING_IMPORTANCE * b)) * (1 + (SCALE_IMPORTANCE * s * s))
				* (1 + (PARTICLES_IMPORTANCE * p)) * enemies * enemies;
	}
}
